home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows 95 / Programming Windows 95.iso / code / CHAP08 / OWNERDRW.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-01  |  8.6 KB  |  237 lines

  1. /*----------------------------------------------
  2.    OWNERDRW.C -- Owner-Draw Button Demo Program
  3.                  (c) Charles Petzold, 1996
  4.   ----------------------------------------------*/
  5.  
  6. #include <windows.h>
  7.  
  8. #define IDC_SMALLER      1
  9. #define IDC_LARGER       2
  10.  
  11. #define BTN_WIDTH        (8 * cxChar)
  12. #define BTN_HEIGHT       (4 * cyChar)
  13.  
  14. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  15.  
  16. HINSTANCE hInst ;
  17.  
  18. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  19.             PSTR szCmdLine, int iCmdShow)
  20.      {
  21.      static char szAppName[] = "OwnerDrw" ;
  22.      MSG         msg ;
  23.      HWND        hwnd ;
  24.      WNDCLASSEX  wndclass ;
  25.  
  26.      hInst = hInstance ;
  27.  
  28.      wndclass.cbSize        = sizeof (wndclass) ;
  29.      wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  30.      wndclass.lpfnWndProc   = WndProc ;
  31.      wndclass.cbClsExtra    = 0 ;
  32.      wndclass.cbWndExtra    = 0 ;
  33.      wndclass.hInstance     = hInstance ;
  34.      wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  35.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  36.      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  37.      wndclass.lpszMenuName  = szAppName ;
  38.      wndclass.lpszClassName = szAppName ;
  39.      wndclass.hIconSm       = LoadIcon (NULL, IDI_APPLICATION) ;
  40.  
  41.      RegisterClassEx (&wndclass) ;
  42.  
  43.      hwnd = CreateWindow (szAppName, "Owner-Draw Button Demo",
  44.                           WS_OVERLAPPEDWINDOW,
  45.                           CW_USEDEFAULT, CW_USEDEFAULT,
  46.                           CW_USEDEFAULT, CW_USEDEFAULT,
  47.                           NULL, NULL, hInstance, NULL) ;
  48.  
  49.      ShowWindow (hwnd, iCmdShow) ;
  50.      UpdateWindow (hwnd) ; 
  51.  
  52.      while (GetMessage (&msg, NULL, 0, 0))
  53.           {
  54.           TranslateMessage (&msg) ;
  55.           DispatchMessage (&msg) ;
  56.           }
  57.      return msg.wParam ;
  58.      }
  59.  
  60. void Triangle (HDC hdc, POINT pt[])
  61.      {
  62.      SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ;
  63.      Polygon (hdc, pt, 3) ;
  64.      SelectObject (hdc, GetStockObject (WHITE_BRUSH)) ;
  65.      }
  66.  
  67. LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  68.      {
  69.      static HWND      hwndSmaller, hwndLarger ;
  70.      static int       cxClient, cyClient, cxChar, cyChar ;
  71.      int              cx, cy ;
  72.      LPDRAWITEMSTRUCT pdis ;
  73.      POINT            pt[3] ;
  74.      RECT             rc ;
  75.  
  76.      switch (iMsg)
  77.           {
  78.           case WM_CREATE :
  79.                cxChar = LOWORD (GetDialogBaseUnits ()) ;
  80.                cyChar = HIWORD (GetDialogBaseUnits ()) ;
  81.  
  82.                          // Create the owner-draw pushbuttons
  83.  
  84.                hwndSmaller = CreateWindow ("button", "",
  85.                                   WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
  86.                                   0, 0, BTN_WIDTH, BTN_HEIGHT,
  87.                                   hwnd, (HMENU) IDC_SMALLER, hInst, NULL) ;
  88.  
  89.                hwndLarger = CreateWindow ("button", "",
  90.                                   WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
  91.                                   0, 0, BTN_WIDTH, BTN_HEIGHT,
  92.                                   hwnd, (HMENU) IDC_LARGER, hInst, NULL) ;
  93.                return 0 ;
  94.  
  95.           case WM_SIZE :
  96.                cxClient = LOWORD (lParam) ;
  97.                cyClient = HIWORD (lParam) ;
  98.  
  99.                          // Move the buttons to the new center
  100.  
  101.                MoveWindow (hwndSmaller, cxClient / 2 - 3 * BTN_WIDTH  / 2,
  102.                                         cyClient / 2 -     BTN_HEIGHT / 2,
  103.                                         BTN_WIDTH, BTN_HEIGHT, TRUE) ;
  104.  
  105.                MoveWindow (hwndLarger,  cxClient / 2 +     BTN_WIDTH  / 2,
  106.                                         cyClient / 2 -     BTN_HEIGHT / 2,
  107.                                         BTN_WIDTH, BTN_HEIGHT, TRUE) ;
  108.                return 0 ;
  109.  
  110.           case WM_COMMAND :
  111.                GetWindowRect (hwnd, &rc) ;
  112.  
  113.                          // Make the window 10% smaller or larger
  114.  
  115.                switch (wParam)
  116.                     {
  117.                     case IDC_SMALLER :
  118.                          rc.left   += cxClient / 20 ;
  119.                          rc.right  -= cxClient / 20 ;
  120.                          rc.top    += cyClient / 20 ;
  121.                          rc.bottom -= cyClient / 20 ;
  122.  
  123.                          break ;
  124.  
  125.                     case IDC_LARGER :
  126.                          rc.left   -= cxClient / 20 ;
  127.                          rc.right  += cxClient / 20 ;
  128.                          rc.top    -= cyClient / 20 ;
  129.                          rc.bottom += cyClient / 20 ;
  130.  
  131.                          break ;
  132.                     }
  133.  
  134.                MoveWindow (hwnd, rc.left, rc.top, rc.right  - rc.left,
  135.                                                   rc.bottom - rc.top, TRUE) ;
  136.                return 0 ;
  137.  
  138.           case WM_DRAWITEM :
  139.                pdis = (LPDRAWITEMSTRUCT) lParam ;
  140.  
  141.                          // Fill area with white and frame it black
  142.  
  143.                FillRect (pdis->hDC, &pdis->rcItem,
  144.                          (HBRUSH) GetStockObject (WHITE_BRUSH)) ;
  145.  
  146.                FrameRect (pdis->hDC, &pdis->rcItem,
  147.                           (HBRUSH) GetStockObject (BLACK_BRUSH)) ;
  148.  
  149.                          // Draw inward and outward black triangles
  150.  
  151.                cx = pdis->rcItem.right  - pdis->rcItem.left ;
  152.                cy = pdis->rcItem.bottom - pdis->rcItem.top  ;
  153.  
  154.                switch (pdis->CtlID)
  155.                     {
  156.                     case IDC_SMALLER :
  157.                          pt[0].x = 3 * cx / 8 ;  pt[0].y = 1 * cy / 8 ;
  158.                          pt[1].x = 5 * cx / 8 ;  pt[1].y = 1 * cy / 8 ;
  159.                          pt[2].x = 4 * cx / 8 ;  pt[2].y = 3 * cy / 8 ;
  160.  
  161.                          Triangle (pdis->hDC, pt) ;
  162.  
  163.                          pt[0].x = 7 * cx / 8 ;  pt[0].y = 3 * cy / 8 ;
  164.                          pt[1].x = 7 * cx / 8 ;  pt[1].y = 5 * cy / 8 ;
  165.                          pt[2].x = 5 * cx / 8 ;  pt[2].y = 4 * cy / 8 ;
  166.  
  167.                          Triangle (pdis->hDC, pt) ;
  168.  
  169.                          pt[0].x = 5 * cx / 8 ;  pt[0].y = 7 * cy / 8 ;
  170.                          pt[1].x = 3 * cx / 8 ;  pt[1].y = 7 * cy / 8 ;
  171.                          pt[2].x = 4 * cx / 8 ;  pt[2].y = 5 * cy / 8 ;
  172.  
  173.                          Triangle (pdis->hDC, pt) ;
  174.  
  175.                          pt[0].x = 1 * cx / 8 ;  pt[0].y = 5 * cy / 8 ;
  176.                          pt[1].x = 1 * cx / 8 ;  pt[1].y = 3 * cy / 8 ;
  177.                          pt[2].x = 3 * cx / 8 ;  pt[2].y = 4 * cy / 8 ;
  178.  
  179.                          Triangle (pdis->hDC, pt) ;
  180.  
  181.                          break ;
  182.  
  183.                     case IDC_LARGER :
  184.  
  185.                          pt[0].x = 5 * cx / 8 ;  pt[0].y = 3 * cy / 8 ;
  186.                          pt[1].x = 3 * cx / 8 ;  pt[1].y = 3 * cy / 8 ;
  187.                          pt[2].x = 4 * cx / 8 ;  pt[2].y = 1 * cy / 8 ;
  188.  
  189.                          Triangle (pdis->hDC, pt) ;
  190.  
  191.                          pt[0].x = 5 * cx / 8 ;  pt[0].y = 5 * cy / 8 ;
  192.                          pt[1].x = 5 * cx / 8 ;  pt[1].y = 3 * cy / 8 ;
  193.                          pt[2].x = 7 * cx / 8 ;  pt[2].y = 4 * cy / 8 ;
  194.  
  195.                          Triangle (pdis->hDC, pt) ;
  196.  
  197.                          pt[0].x = 3 * cx / 8 ;  pt[0].y = 5 * cy / 8 ;
  198.                          pt[1].x = 5 * cx / 8 ;  pt[1].y = 5 * cy / 8 ;
  199.                          pt[2].x = 4 * cx / 8 ;  pt[2].y = 7 * cy / 8 ;
  200.  
  201.                          Triangle (pdis->hDC, pt) ;
  202.  
  203.                          pt[0].x = 3 * cx / 8 ;  pt[0].y = 3 * cy / 8 ;
  204.                          pt[1].x = 3 * cx / 8 ;  pt[1].y = 5 * cy / 8 ;
  205.                          pt[2].x = 1 * cx / 8 ;  pt[2].y = 4 * cy / 8 ;
  206.  
  207.                          Triangle (pdis->hDC, pt) ;
  208.  
  209.                          break ;
  210.                     }
  211.  
  212.                          // Invert the rectangle if the button is selected
  213.  
  214.                if (pdis->itemState & ODS_SELECTED)
  215.                     InvertRect (pdis->hDC, &pdis->rcItem) ;
  216.  
  217.                          // Draw a focus rectangle if the button has the focus
  218.  
  219.                if (pdis->itemState & ODS_FOCUS)
  220.                     {
  221.                     pdis->rcItem.left   += cx / 16 ;
  222.                     pdis->rcItem.top    += cy / 16 ;
  223.                     pdis->rcItem.right  -= cx / 16 ;
  224.                     pdis->rcItem.bottom -= cy / 16 ;
  225.  
  226.                     DrawFocusRect (pdis->hDC, &pdis->rcItem) ;
  227.                     }
  228.  
  229.                return 0 ;
  230.  
  231.           case WM_DESTROY :
  232.                PostQuitMessage (0) ;
  233.                return 0 ;
  234.           }
  235.      return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
  236.      }
  237.